from PyQt5.QtWidgets import QWidget, QGraphicsView, QGraphicsScene, QGraphicsLineItem, QVBoxLayout, QStatusBar, QSizePolicy
from PyQt5.QtCore import Qt, QPointF, pyqtSignal, QRectF
from PyQt5.QtGui import QPainter, QPen, QPolygonF, QTransform

import threading

from trace_visualizer_py.common import *


class TraceView(QGraphicsView):
    sig_mouse_draw_finished = pyqtSignal(list)  # 定义绘制完成信号，携带鼠标绘制的点列表，用于鼠标绘制完成后ros发布鼠标轨迹点

    def __init__(self, scene):
        super().__init__(scene)
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.setMinimumSize(100,100)
        self.setRenderHint(QPainter.Antialiasing)
        # self.setDragMode(QGraphicsView.ScrollHandDrag)  # 启用手形拖动
        self.setDragMode(QGraphicsView.NoDrag)  # 禁用默认拖动
        self.dragging = False  # 标记是否正在拖拽
        self.last_pos = None  # 记录上一次鼠标位置
        self.drawing = False  # 标记是否正在绘制
        self.scale(1 / 1.5, 1 / 1.5)
        self.scene().update_axes(self)  # 缩放后更新坐标轴

    def mousePressEvent(self, event):
        if event.button() == Qt.RightButton:
            self.dragging = True
            self.last_pos = event.pos()
        elif event.button() == Qt.LeftButton:
            self.drawing = True
            # 清空场景内容
            self.scene().clear_content()
            
            # 将视图坐标转换为场景坐标
            map_x, map_y = self.__convet_mouse_xy_to_map(event.pos())
            self.scene().add_point(map_x, map_y, is_mouse=True)
            # print(f'鼠标绘制：map_point:{map_x}, {map_y}')
            self.scene().draw_start(map_x, map_y)

        super().mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if self.dragging:
            delta = event.pos() - self.last_pos
            self.horizontalScrollBar().setValue(self.horizontalScrollBar().value() - delta.x())
            self.verticalScrollBar().setValue(self.verticalScrollBar().value() - delta.y())
            self.last_pos = event.pos()
        elif self.drawing:
            map_x, map_y = self.__convet_mouse_xy_to_map(event.pos())
            self.scene().add_point(map_x, map_y, is_mouse=True)
            
        super().mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.RightButton:
            self.dragging = False
        elif event.button() == Qt.LeftButton:
            self.drawing = False
            map_x, map_y = self.__convet_mouse_xy_to_map(event.pos())
            self.scene().draw_end(map_x, map_y)
            
            # 获取鼠标绘制的轨迹点
            points = self.scene().get_mouse_points()
            # 发送轨迹点
            self.sig_mouse_draw_finished.emit(points)
        super().mouseReleaseEvent(event)

    
    def wheelEvent(self, event):
        # 实现鼠标滚轮缩放
        zoom_factor = 1.1  # 缩放因子
        if event.angleDelta().y() > 0:
            self.scale(zoom_factor, zoom_factor)
        else:
            self.scale(1 / zoom_factor, 1 / zoom_factor)
        self.scene().update_axes(self)  # 缩放后更新坐标轴

    def __convet_mouse_xy_to_map(self, qpoint):
        scene_pos = self.mapToScene(qpoint)
        map_x, map_y = self.scene().convert_point_to_map(scene_pos.x(), scene_pos.y())
        return map_x, map_y


class TraceWidget(QWidget):
    def __init__(self, view):
        super().__init__()
        self.setMinimumSize(100, 100)
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        self.setSizePolicy(sizePolicy)

        layout = QVBoxLayout()
        self.setLayout(layout)

        self.view = view
        self.scene = common_data['scene_map']
        self.scene.sig_ship_move.connect(self.update_status_bar)  # 连接信号和槽

        # 获取视图的视口大小
        viewport_size = self.view.viewport().size()
        # print(viewport_size)
        # 将视图坐标的左下角转换为场景坐标
        scene_bottom_left = self.view.mapToScene(viewport_size.width()//2, viewport_size.height()//2)

        # p = QPointF(viewport_size.width() / 2, viewport_size.height() / 2)

        self.view.centerOn(scene_bottom_left)  # 初始居中
        self.view.scale(1, -1)  # Y轴反向

        
        layout.addWidget(self.view)

        self.status_bar = QStatusBar()  # 创建状态栏
        layout.addWidget(self.status_bar)

        # 示例：设置矩形绘图区的长宽
        self.scene.set_pool_area(80, 60)  # 单位m
        self.scene.draw_pool_area()

    def add_point(self, x, y):
        if common_data['cfg_basic'].get('shipState') == ShipState.START:
            self.scene.add_point(x, y)
        else:
            self.scene.draw_ship(x, y, common_data['cfg_basic'].get('shipAngle'))

    def update_status_bar(self, pos):
        """更新状态栏显示鼠标当前的场景坐标"""
        self.status_bar.showMessage(f"航行器位置: ({pos.x():.2f}, {pos.y():.2f})")

    def resize_pool(self, length, width):
        self.scene.set_pool_area(length, width)
        self.scene.clear_content()

    def update_uwb_location(self, x1, y1, x2, y2, x3, y3):
        self.scene.set_uwb_pos(x1, y1, x2, y2, x3, y3)
        self.scene.clear_content()
    

common_data['view_trace'] = TraceView(common_data['scene_map'])
common_data['widget_trace'] = TraceWidget(common_data['view_trace'])